package com.greenline.push.service.core.utils.mail.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.greenline.push.dal.util.BizCommonUtils;
import com.greenline.push.service.core.utils.mail.MailService;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 邮件发送业务
 * 
 * @Type MailSendManager
 * @Desc 邮件业务接口
 * @author wangbiao
 * @date 2014-5-21
 * @Version V1.0
 */
public class MailSendManagerImpl implements com.greenline.push.service.core.utils.mail.MailSendManager {

    private static final Log logger = LogFactory.getLog(MailSendManagerImpl.class);

    /**
     * freemarker config
     */
    private Configuration freemarker_cfg = null;

    @Resource
    private MailService mailService;

    /**
     * 空白模版
     */
    private static final String MAIL_TEMPLATE_BLANK = "blank";

    /**
     * txt后缀
     */
    private static final String POSTFIX_TXT = ".txt";

    /**
     * result文件夹
     */
    private static final String FOLDER_RESULT = "/result/";

    /**
     * 邮件模版路径
     */
    private String templatePath;

    public String getTemplatePath() {
        return templatePath;
    }

    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }

    @Override
    public void sendMail(String subject, String to, String content) {
        Map<String, String> data = new HashMap<String, String>();
        data.put("content", subject + "\r" + content);
        mailService.send(MAIL_TEMPLATE_BLANK, to, data, false);
    }

    @Override
    public void sendMail(String subject, String to, Map<Object, Object> dataMap, String ftlTemplateName) {
        // 临时文件名：当前时间+邮件地址
        String tempfileName = System.currentTimeMillis() + "_" + to + POSTFIX_TXT;
        // 模版渲染
        this.renderTemplate(ftlTemplateName, dataMap, FOLDER_RESULT, tempfileName);
        // 读取替换变量后的txt文件
        String sPath = templatePath + FOLDER_RESULT + tempfileName;
        String content = BizCommonUtils.readTxtFile(sPath);
        // 发送邮件
        sendMail(subject, to, content);
        // 删除临时文件
        BizCommonUtils.deleteFile(sPath);
    }

    /**
     * 获取freemarker的配置
     * 
     * @throws IOException
     */
    private Configuration getFreeMarkerCFG(String rootDir) throws IOException {
        if (null == freemarker_cfg) {
            freemarker_cfg = new Configuration();
            freemarker_cfg.setNumberFormat("#");
            freemarker_cfg.setEncoding(Locale.CHINA, "UTF-8");
            freemarker_cfg.setDirectoryForTemplateLoading(new File(rootDir));
        }
        return freemarker_cfg;
    }

    /**
     * 解析ftl模版，再生成指定格式文件
     * 
     * @param templateFileName ftl模版文件名
     * @param modelMap 需要替换的变量
     * @param filePath 生成文件路径
     * @param fileName 生成文件名
     */
    private void renderTemplate(String templateFileName, Map<Object, Object> modelMap, String filePath, String fileName) {
        Writer out = null;
        try {
            // 获取模版信息
            Template t = getFreeMarkerCFG(templatePath).getTemplate(templateFileName);
            // 递归创建子目录
            BizCommonUtils.creatDirs(templatePath, filePath);
            File afile = new File(templatePath + "/" + filePath + "/" + fileName);
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile), "UTF-8"));
            t.process(modelMap, out);
        } catch (TemplateException e) {
            logger.error("Error while processing freemarker template." + templateFileName, e);
        } catch (IOException e) {
            logger.error("Error while generate static File." + fileName, e);
        } finally {
            try {
                if (null != out) {
                    out.flush();
                    out.close();
                }
            } catch (IOException e) {
                logger.error("Error while close writer.", e);
            }
        }
    }
}
